- 在使用hibernate的时候,因为错误的cascade和inverse的配置,对save,update,delete coding产生了一些不必要的异常,浪费时间去debug,打包测试发版等
- 做了一些基本测试,总结如下
- cascade的原理,使用,以及可能的坑
- inverse使用,以及如何配合cascade
- github上有个hibernate.demo project可做测试原码参考,参见其中com.pazu.hibernate.demo.CascadeTest.java中的测试用例和注释
cascade
why cascade & what is cascade
- 很简单,在使用hibernate中,如果碰到1-n的关系的对象A&B,在保存的时候,正常应该是有1+n条sql去分别保存这些对象。在hibernate看来这些操作是重复的,so增加了cascade属性去解决类似的重复操作问题
- cascade可以基本理解为,对一个pojo做指定操作时,如果该pojo中存在其他pojo的mapping关系且值非null,这个时候就会根据cascade的配置来对关联对象触发相同操作,如save,update or delete
basic usage
- default value is nono
- value contains : none, save-update, delete, all, orphan-delete, 最后一个并不常用
- 如果想使用cascade来保存关联关系的话,需要明确
- one-to-one&one-to-many的情况下(其实本质讲,one-to-one是一个unique的one-to-many,在hibernate看来),决定关联关系是否能保存的关键是fk(在这里不考虑hibernate支持的其他两种关联关系方式,如主键关联)field所在的pojo是否对应值被set,并且该pojo是否被保存了
- 而many-to-many mapping中,无论哪一方被set,默认是都会更新关联关系的,这个取决于inverse
- 具体可以参见cascade的test类,在上面提到过的
inverse
whats inverse
- inverse的出现,是解决hibernate在触发cascade的情况下,有些cascade是比较低效的。假设A&B存在关联关系one-to-many,如我想使用A的cascade的save&delete,但在update A的情况下,关联B list会create n条update B的sql,and这些并不是我希望看到的。so 配置inverse可以解决这个问题
usage
- inverse 默认值是false
- 只在hibernate mapping的one-to-many & many-to-many collection tag上起作用,如bag,list,set等